#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <net/if.h>

#define CAN_INTERFACE "can0"  // 这里设置你使用的 CAN 接口

// 函数：设置 CAN 接口
int setup_can_socket(const char *interface_name) {
    struct ifreq ifr;
    struct sockaddr_can addr;
    int s;

    // 创建一个 socket
    s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    if (s < 0) {
        perror("Socket creation failed");
        return -1;
    }

    // 获取 CAN 接口信息
    strncpy(ifr.ifr_name, interface_name, sizeof(ifr.ifr_name) - 1);
    if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
        perror("IOCTL failed to get interface index");
        close(s);
        return -1;
    }

    // 设置 sockaddr_can
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;

    // 绑定 socket 到指定的 CAN 接口
    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("Bind failed");
        close(s);
        return -1;
    }

    return s;
}

// 函数：接收 CAN 帧
void receive_can_frame(int socket) {
    struct can_frame frame;
    int nbytes;

    // 接收数据帧
    nbytes = read(socket, &frame, sizeof(struct can_frame));
    if (nbytes < 0) {
        perror("Read failed");
        return;
    }

    // 打印接收到的 CAN 帧数据
    printf("Received CAN frame: ID=0x%X, DLC=%d, Data=", frame.can_id, frame.can_dlc);
    for (int i = 0; i < frame.can_dlc; i++) {
        printf("0x%02X ", frame.data[i]);
    }
    printf("\n");
}

int main() {
    int socket;
    int frame_count = 0;

    // 设置 CAN socket
    socket = setup_can_socket(CAN_INTERFACE);
    if (socket < 0) {
        return -1;
    }

    // 接收 3 个数据帧
    while (frame_count < 3) {
        printf("Waiting for CAN frame %d...\n", frame_count + 1);
        receive_can_frame(socket);  // 接收数据帧
        frame_count++;
    }

    // 关闭 socket
    close(socket);

    return 0;
}

